﻿using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Data;
using System.Data.SQLite;
using System.Text.RegularExpressions;


namespace CCPSIP.AB
{
    /// <summary>CCPSIP_008：上傳本機通訊錄 API</summary>
    /// idHeader = 裝置 UUID 前八碼。iOS 請使用 [CCPCrypto getIdHeader] 呼叫。
    /// checkcode = 裝置限時驗證碼。iOS 請使用 [CCPCrypto getCheckcode] 呼叫。
    /// 上傳檔案 = AddressBook 整合 SQLite 檔。

    public class contacts_upload : IHttpHandler
    {
        private string kUploadDir = ChrisKit.RootDir + "CCPSIP\\ContactsUpload";//ios.ccp

        // iCloud: Limits for Contacts
        // http://support.apple.com/kb/HT4489
        private const int kFileSizeLimit = 30 * 1048576;//30MB
        private const int kPhoneRecordLimit = 3 * 25000;//3 phones for each contact


        public void ProcessRequest(HttpContext context)
        {
            HttpRequest req = context.Request;
            HttpResponse resp = context.Response;
            resp.ContentType = "text/plain";
            resp.ContentEncoding = System.Text.Encoding.UTF8;
            DateTime reqTime = DateTime.Now;
            string resultStr = "";

            string TempFileName = "";


            try
            {
                //【01】取得POST參數，驗證身分
                //
                string idHeader = req.Form["idHeader"];
                string checkcode = req.Form["checkcode"];

                SipUserInfo userInfo = SipKit.GetUserInfo(idHeader, checkcode, req);
                if (userInfo == null)
                {
                    throw new Exception("Error_01: Cannot identify this device");//無法識別此裝置
                }


                //【02】取得上傳的檔案
                //
                if (req.Files.Count < 1 || req.Files[0].ContentLength < 1024)
                {
                    throw new Exception("Error_02: No upload file");//沒有上傳檔案
                }
                else if (req.Files[0].ContentLength > kFileSizeLimit)
                {
                    throw new Exception("Error_02: File size exceeds limit");//檔案大小超過上限
                }
                TempFileName = Path.GetTempFileName();
                req.Files[0].SaveAs(TempFileName);


                //【03】SQLite檔案分析：讀取電話號碼
                //
                HashSet<string> phoneNumSet = new HashSet<string>();

                SQLiteConnection connSQLite = new SQLiteConnection(@"Data Source=" + TempFileName);
                try
                {
                    connSQLite.Open();

                    string selStr3 = "SELECT Value FROM CCPSIP_CONTACT_DETAIL"
                      + " WHERE TYPE='Phone_Num' AND LENGTH(Value)>=8";
                    SQLiteCommand selCmd3 = new SQLiteCommand(selStr3, connSQLite);
                    SQLiteDataAdapter adapter3 = new SQLiteDataAdapter(selCmd3);
                    DataSet dataSet3 = new DataSet();
                    adapter3.Fill(dataSet3);

                    foreach (DataRow row in dataSet3.Tables[0].Rows)
                    {
                        string phoneNum = Convert.ToString(row["Value"]);
                        phoneNum = ChrisKit.CleanPhoneNum(phoneNum);//清理電話號碼

                        if (phoneNum.StartsWith("+"))
                            phoneNum = phoneNum.Remove(0, 1);//去掉國碼開頭"+"
                        if (phoneNum.StartsWith("0"))
                            phoneNum = userInfo.CountryCode + phoneNum.Remove(0, 1);//開頭的"0"替換為User國碼

                        if (Regex.IsMatch(phoneNum, "^[0-9]{8,20}$"))
                            phoneNumSet.Add(phoneNum);
                        if (phoneNumSet.Count >= kPhoneRecordLimit)
                            break;//不可超過限制筆數
                    }

                    selCmd3.Dispose();//Release the SQLite file
                }
                catch (Exception ex)
                {
                    string errorMsg = string.Format("Error_03: SQLite file error. ({0})", ex.Message);
                    throw new Exception(errorMsg);//SQLite讀取錯誤
                }
                finally
                {
                    connSQLite.Close();
                }


                if (phoneNumSet.Count > 0)
                {
                    List<string> phoneList = new List<string>(phoneNumSet);

                    //【04】把認識的門號加到 CCPSIP 朋友清單(只會加有效User)
                    //
                    OracleKitContact.AddFriends(userInfo, phoneList.ToArray());


                    //【05】另存檔案
                    //
                    string saveDir = string.Format(@"{0}\{1}", kUploadDir, userInfo.SIP_Num);
                    if (!Directory.Exists(saveDir))
                    {
                        Directory.CreateDirectory(saveDir);
                    }

                    string savePath = string.Format(@"{0}\{1}_{2:yyyyMMdd_HHmmss}.sqlite", saveDir, userInfo.SIP_Num, reqTime);
                    if (!File.Exists(savePath))
                    {
                        File.Copy(TempFileName, savePath, false);
                    }
                }


                //【99】回傳OK
                //
                resultStr = "OK";
            }
            catch (Exception ex)
            {
                resp.ContentType = "application/xml";
                resultStr = ChrisKit.Ex2Xml(ex, false);
            }
            finally
            {
                if (File.Exists(TempFileName))
                {
                    File.Delete(TempFileName);//清理暫存檔
                }
                int contentLength = resp.ContentEncoding.GetByteCount(resultStr);
                resp.AppendHeader("Content-Length", contentLength.ToString());
                resp.Write(resultStr);
                resp.Flush();
                resp.Close();
            }
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

    }
}
